package com.ubtechinc.cruzr.launcher2.widget;

import android.graphics.Rect;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;

import com.ubtechinc.cruzr.launcher2.model.AppManger;
import com.ubtechinc.cruzr.launcher2.utlis.LogUtils;
import com.ubtechinc.cruzr.launcher2.utlis.UbtCantans;

public class HorizontalPageLayoutManager extends RecyclerView.LayoutManager {
    private int rows;
    private int columns;
    private int pageSize = 0;
    private int onePageSize;
    private int itemWidthUsed;
    private int itemHeightUsed;
    private int totalWidth = 0;
    private int offsetX = 0;

    @Override
    public RecyclerView.LayoutParams generateDefaultLayoutParams() {
//        return new StaggeredGridLayoutManager.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
//                ViewGroup.LayoutParams.WRAP_CONTENT);
        return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
    }

    public HorizontalPageLayoutManager(int rows, int columns) {
        this.rows = rows;
        this.columns = columns;
        this.onePageSize = rows * columns;
    }

    @Override
    public boolean canScrollHorizontally() {
        return true;
    }


    @Override
    public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler, RecyclerView.State state) {
        detachAndScrapAttachedViews(recycler);
        //向左滑动dx为正值，向右滑动为负值。
        Log.i("LayoutManager", "当前的dx值为： " + dx);
        int newX = offsetX + dx;
        int result = dx;
        if (newX > totalWidth) {
            result = totalWidth - offsetX;
        } else if (newX < 0) {
            result = 0 - offsetX;
        }
        offsetX += result;
        offsetChildrenHorizontal(-result);
        recycleAndFillItems(recycler, state);
        return result;
    }

    private SparseArray<Rect> allItemFrames = new SparseArray<>();

    /**
     * 获取可用的宽度
     *
     * @return 可用宽度
     */
    private int getUsableWidth() {
        return getWidth() - getPaddingLeft() - getPaddingRight();
    }

    private int getUsableHeight() {
        return getHeight() - getPaddingTop() - getPaddingBottom();
    }


    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        if (getItemCount() == 0) {
            removeAndRecycleAllViews(recycler);
            return;
        }
        if (state.isPreLayout()) {
            return;
        }
        //获取每个Item的平均宽高
        int itemWidth = getUsableWidth() / columns;
        int itemHeight = getUsableHeight() / rows;
        //计算宽高已经使用的量，主要用于后期测量
        itemWidthUsed = (columns - 1) * itemWidth;
        itemHeightUsed = (rows - 1) * itemHeight;
        //计算总的页数
        computePageSize(state);
        //计算可以横向滚动的最大值
        totalWidth = (pageSize - 1) * getWidth();
        //分离view
        detachAndScrapAttachedViews(recycler);
        int count = getItemCount();
//        Log.e("launcher","launcher count = " + count);
        for (int p = 0; p < pageSize; p++) {
            for (int r = 0; r < rows; r++) {
                for (int c = 0; c < columns; c++) {
                    int index = p * onePageSize + r * columns + c;
                    if (index == count) {
                        //跳出多重循环
                        r = rows;
                        p = pageSize;
                        break;
                    }
                    IclineRelaiveLayout view = (IclineRelaiveLayout) recycler.getViewForPosition(index);
                    addView(view);
                    if (AppManger.get().isAppDeleteState()) {
                        view.startDeleteAinimation();
                    }
                    //测量item
                    measureChildWithMargins(view, itemWidthUsed, itemHeightUsed);
                    int width = getDecoratedMeasuredWidth(view);
                    int height = getDecoratedMeasuredHeight(view);

                    //记录显示范围
                    Rect rect = allItemFrames.get(index);
                    if (rect == null) {
                        rect = new Rect();
                    }
                    if (isClockFirst()) {
                        int p1;
                        int c1;
                        int r1;
//                        Log.i("LayoutManager", "index= " + index + "  width= " + width + "  height= " + height);
                        if (index == 0) {
                            int x = p * getUsableWidth() + c * itemWidth;
                            int y = r * itemHeight;
                            rect.set(x, y, width + x, height + y + height);
                        } else if (index == 1) {
                            int left = p * getUsableWidth() + c * itemWidth;
                            int right = p * getUsableWidth() + (columns-1) * itemWidth+width;
                            int y = r * itemHeight;
                            rect.set(left, y, right, height + y);
                        } else {
                            int pp[] = getViewPosition(index);
                            p1 = pp[0];
                            r1 = pp[1];
                            c1 = pp[2];
                            int x = p1 * getUsableWidth() + c1 * itemWidth;
                            int y = r1 * itemHeight;
                            rect.set(x, y, width + x, height + y);
                        }
                    } else {
                        int x = p * getUsableWidth() + c * itemWidth;
                        int y = r * itemHeight;
                        rect.set(x, y, width + x, height + y);
                    }
                    Log.i("LayoutManager", "index= " + index + "  width= " + width + "  height= " + height);
                    allItemFrames.put(index, rect);
                }
            }
            //每一页循环以后就回收一页的View用于下一页的使用
            removeAndRecycleAllViews(recycler);
        }
        recycleAndFillItems(recycler, state);
    }

    /**
     * 计算每个Item偏移后的位置，返回偏移后的页数、row、columu
     *
     * @params : [index] 初始位置
     * @author :ruiqiang
     */
    private int[] getViewPosition(int index) {
//        int newindex = index + 1;
        int newindex = index + 3;
        int[] positon = new int[3];
        int pagecount = rows * columns;
        int page = newindex / pagecount;
        int r;
        int c;
//        if (index < columns) {
//            c = index % columns;
//            r = index / columns;
//        } else {
//            c = (newindex - page * pagecount) % columns;
//            r = (newindex - page * pagecount) / columns;
//        }
        if (index <= columns) {
            c = (index - 1) % columns;
            r = 1;
        } else {
            c = (newindex - page * pagecount) % columns;
            r = (newindex - page * pagecount) / columns;
        }
        positon[0] = page;
        positon[1] = r;
        positon[2] = c;
        return positon;
    }

    private void computePageSize(RecyclerView.State state) {
        int count;
        if (isClockFirst()) {
            count = state.getItemCount() + 1;
        } else {
            count = state.getItemCount();
        }
        pageSize = count / onePageSize + (count % onePageSize == 0 ? 0 : 1);
    }

    @Override
    public void onDetachedFromWindow(RecyclerView view, RecyclerView.Recycler recycler) {
        super.onDetachedFromWindow(view, recycler);
        offsetX = 0;
    }

    private void recycleAndFillItems(RecyclerView.Recycler recycler, RecyclerView.State state) {
        try {
            if (state.isPreLayout()) {
                return;
            }

            Rect displayRect = new Rect(getPaddingLeft() + offsetX,
                    getPaddingTop(),
                    getWidth() - getPaddingLeft() - getPaddingRight() + offsetX,
                    getHeight() - getPaddingTop() - getPaddingBottom());
            Rect childRect = new Rect();
            for (int i = 0; i < getChildCount(); i++) {
                IclineRelaiveLayout child = (IclineRelaiveLayout) getChildAt(i);
                childRect.left = getDecoratedLeft(child);
                childRect.top = getDecoratedTop(child);
                childRect.right = getDecoratedRight(child);
                childRect.bottom = getDecoratedBottom(child);
                if (!Rect.intersects(displayRect, childRect)) {
                    removeAndRecycleView(child, recycler);
                }
            }
            int itemcount = getItemCount();
            for (int i = 0; i < itemcount; i++) {
                Rect rect = allItemFrames.get(i);
                if (rect != null && Rect.intersects(displayRect, rect)) {
                    View view = recycler.getViewForPosition(i);
                    addView(view);
                    if (i == 0) {
                        if (isClockFirst()) {
                            measureChildWithMargins(view, itemWidthUsed, 0);
//                            measureChildWithMargins(view, itemWidthUsed, itemHeightUsed);
                        } else {
                            measureChildWithMargins(view, itemWidthUsed, itemHeightUsed);
                        }
                    } else if (i == 1) {
                        measureChildWithMargins(view, getUsableWidth() / columns, itemHeightUsed);
                    } else {
                        measureChildWithMargins(view, itemWidthUsed, itemHeightUsed);
                    }
                    Log.i("LayoutManager", "i = " + i +
                            "  offsetX = " + offsetX + "  rect.left = " + rect.left
                            + "  rect.top = " + rect.top + "  rect.right = " + rect.right + "  rect.bottom = " + rect.bottom);

                    layoutDecorated(view, rect.left - offsetX, rect.top, rect.right - offsetX, rect.bottom);
                }
            }
        } catch (IndexOutOfBoundsException e) {
            e.printStackTrace();
            LogUtils.e("launcher出现数据越界");
        }
    }

    @Override
    public int computeHorizontalScrollRange(RecyclerView.State state) {
        computePageSize(state);
        return pageSize * getWidth();
    }

    @Override
    public int computeHorizontalScrollOffset(RecyclerView.State state) {
        return offsetX;
    }

    @Override
    public int computeHorizontalScrollExtent(RecyclerView.State state) {
        return getWidth();
    }

    public boolean isClockFirst() {
        return UbtCantans.CLOCK_VISIBLE;
    }

    public int getRows() {
        return rows;
    }

    public int getColumns() {
        return columns;
    }
}
